package com.authine.cloudpivot.ext.service.impl;

import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.facade.SystemManagementFacade;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.system.RelatedCorpSettingModel;
import com.authine.cloudpivot.engine.domain.organization.User;
import com.authine.cloudpivot.engine.domain.runtime.BizWorkitem;
import com.authine.cloudpivot.engine.enums.type.OrgSyncType;
import com.authine.cloudpivot.engine.service.organization.UserService;
import com.authine.cloudpivot.engine.service.runtime.ExtProcessTaskServcie;
import com.authine.cloudpivot.ext.domain.oaSendToDo.OaDeleteToDo;
import com.authine.cloudpivot.ext.domain.oaSendToDo.OaResult;
import com.authine.cloudpivot.ext.domain.oaSendToDo.OaSendToDo;
import com.authine.cloudpivot.ext.service.OaToFacade;
import com.authine.cloudpivot.ext.util.ItemTypeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author hxd
 * @Date 2021/11/25 11:17
 * @Description 已作废
 **/
@Deprecated
//@Service
@Slf4j
public class MessagePushServiceImpl implements ExtProcessTaskServcie {

    @Value("${cloudpivot.oa.sendTodo:https://testoa.mszq.com/api/sys-notify/sysNotifyTodoRestService/sendTodo}")
    private String sendTodoUrl;
    @Value("${cloudpivot.oa.deleteTodo:https://testoa.mszq.com/api/sys-notify/sysNotifyTodoRestService/deleteTodo}")
    private String deleteTodoUrl;
    @Value("${cloudpivot.oa.itemPcUrl:{}/websso/index.html#/form/detail?workitemId={}&workflowInstanceId={}}")
    private String itemPcUrl;
    @Value("${cloudpivot.oa.itemMobileUrl:{}/mobile?corpId=ding8cd30f4e72d2c55f35c2f4657eb6378f&agentId=714770295#/form/detail?workitemId={}&workflowInstanceId={}}")
    private String itemMobileUrl;
    @Value("${cloudpivot.oa.authentic}")
    private String authentic;

    private String host;

    private static final String subject = "请审批{}";


    @Autowired
    private UserService userService;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    SystemManagementFacade systemManagementFacade;
    @Autowired
    BizObjectFacade bizObjectFacade;

    @Autowired
    OaToFacade oaToFacade;

    ScheduledExecutorService delayThreadPool = Executors.newScheduledThreadPool(5);

    @Override
    public BizWorkitem createProcessTaskEvent( BizWorkitem bizWorkitem) {

        try {
            sendTodo(bizWorkitem);
        } catch (Exception e) {
            log.error("\n=============发送oa待办 系统异常:{}",e);
            saveLog(bizWorkitem, ItemTypeUtils.db,e.getMessage());
        }

        return null;
    }

    @Override
    public void completedProcessTaskEvent( BizWorkitem bizWorkitem) {

        //延时三秒执行
        delayThreadPool.schedule(()->{
            try {
                deleteToDo(bizWorkitem);
            } catch (Exception e) {
                log.error("\n=============发送oa待办 系统异常:{}",e);
                saveLog(bizWorkitem, ItemTypeUtils.yb,e.getMessage());
            }
        },4, TimeUnit.SECONDS);


    }





    
    
    public Map<String,Object> sendTodo(BizWorkitem item){
        log.info("\n=============发送oa待办>>>item={}", JSON.toJSONString(item));
        MapBuilder<String, Object> rstBuild = MapBuilder.create(new HashMap<String, Object>()).put("code","1");
        String appCode = item.getAppCode();

        log.info("oa待办推送,appCode={}",appCode);

        String oaAppName = oaToFacade.getOaAppName(appCode);

        if (oaAppName == null){
            return rstBuild.put("msg",StrUtil.format("{}应用不在配置中",appCode)).build();
        }





        User user = userService.get(item.getParticipant());

        if (user == null){
            log.info("\n==============发送oa待办失败,待办参与者获取失败,Participant:={}",item.getParticipant());

            return rstBuild.put("msg","参与者用户不存在").build();

        }


        OaSendToDo oaSendToDo = new OaSendToDo(item.getWorkflowCode(),item.getId(),
                StrUtil.format(subject,item.getInstanceName()),
                getUrl(item,itemPcUrl),
                getUrl(item,itemMobileUrl),
                1,
                getTargetJsonStr(user),
                DateFormatUtils.format(item.getStartTime(),"yyyy-MM-dd HH:mm:ss"));

        oaSendToDo.setAppName(oaAppName);

        log.info("\n==============发送oa待办 参数: oaSendToDo={}",JSONObject.toJSONString(oaSendToDo));

        postForEntity(sendTodoUrl, oaSendToDo );


        return rstBuild.put("code","0").build();
    }


    private void saveLog(BizWorkitem item,String itemType,String msg){

        MapBuilder<String, Object> bizMap = MapBuilder.create(new HashMap<String, Object>());

        bizMap.put("instName",item.getWorkflowCode())
                .put("instModelName",item.getInstanceName())
                .put("approval",item.getParticipantName())
                .put("instId",item.getInstanceId())
                .put("itemId",item.getId())
                .put("rst","失败")
                .put("msg",msg)
                .put("itemType",itemType) ;

        BizObjectCreatedModel bizObject = new BizObjectCreatedModel("oaTodoOpt", bizMap.build(), false);

        String s = bizObjectFacade.saveBizObject(item.getParticipant(), bizObject, false);

    }

    public Map<String,Object> deleteToDo(BizWorkitem item){
        log.info("\n=============发送oa待办删除>>>item={}", JSON.toJSONString(item));
        MapBuilder<String, Object> rstBuild = MapBuilder.create(new HashMap<String, Object>()).put("code","1");

        String appCode = item.getAppCode();

        log.info("oa待办删除,appCode={}",appCode);

        String oaAppName = oaToFacade.getOaAppName(appCode);

        if (oaAppName == null){
            return rstBuild.put("msg",StrUtil.format("{}应用不在配置中",appCode)).build();
        }

        User user = userService.get(item.getParticipant());

        if (user == null){
            log.info("\n==============发送oa待办删除失败,待办参与者获取失败,Participant:={}",item.getParticipant());
            return rstBuild.put("msg","参与者用户不存在").build();
        }
        OaDeleteToDo oaDeleteToDo = new OaDeleteToDo(item.getWorkflowCode(),item.getId(), 1);

        log.info("\n==============发送oa待办删除 参数: oaSendToDo={}",JSONObject.toJSONString(oaDeleteToDo));

        postForEntity(deleteTodoUrl, oaDeleteToDo );
        return rstBuild.put("code","0").build();

    }


    private  String getTargetJsonStr(User user){
        JSONObject target = new JSONObject();
        target.put("LoginName",user.getUsername());
        return  target.toJSONString();
    }

    private String getUrl(BizWorkitem item,String url){

        List<RelatedCorpSettingModel> list = systemManagementFacade.getAllRelatedCorpSettingModel();

        if (StringUtils.isEmpty(host)){
            host = list.stream().filter(l -> l.getSyncType() == OrgSyncType.PULL).findFirst().orElseGet(() -> list.get(0)).getPcServerUrl();
        }

        return StrUtil.format(url,host,item.getId(),item.getInstanceId());
    }

    private void postForEntity(String url,Object param){
        HttpHeaders headers = new HttpHeaders();

        String authHeader = "Basic " + Base64Utils.encodeToString(authentic.getBytes(Charset.forName("UTF-8")));
        headers.set("Authorization", authHeader );

        HttpEntity stringHttpEntity = new HttpEntity( param, headers);

        ResponseEntity<OaResult> rest = restTemplate.postForEntity(url, stringHttpEntity, OaResult.class);

        OaResult body = rest.getBody();
        log.info("\n==============发送oa待办操作 响应: rest={}",JSONObject.toJSONString(rest));

        if (body == null){
            log.info("\n==============发送oa待办操作 失败");
            throw new RuntimeException(JSONObject.toJSONString(rest));
        }else if (body.getReturnState() == null || body.getReturnState().intValue() !=2){

            if (body.getMessage() != null && body.getMessage().contains("待办所属人")){
                return;
            }

            log.info("\n==============发送oa待办操作 失败");
            throw new RuntimeException(JSONObject.toJSONString(body));


        }
    }
}
